
export 'src/handler/audio_output_device_handler.dart';
export 'src/bean/bean.dart' show BleDevice;

import 'dart:async';
import 'dart:io';

import 'package:flutter/cupertino.dart';

import 'src/bean/bean.dart';
import 'src/platform_interface/audio_output_device_new_platform_interface.dart';
import 'src/util/util.dart';

class AudioOutputDeviceNew with WidgetsBindingObserver{

  static final AudioSessionUtil _audioSessionUtil = AudioSessionUtil.instance;

  static AudioOutputDeviceNewPlatform get _instance => AudioOutputDeviceNewPlatform.instance;

  Stream<bool> get classicDeviceDisconnected => _instance.classicDeviceDisconnected;

  Future<String?> _getPlatformVersion() {
    return _instance.getPlatformVersion();
  }

  /*void enableLog({
    required enable
  }) {
    _audioSessionUtil.enableLog(enable: enable);
  }*/

  bool _hasInit = false;
  Type? handlerType;

  Future<void> initAudioSession({
    OnDevicesChanged? onDevicesChanged,
    OnDevices? onDevices,
    Type? handlerType,
  }) async{
    this.handlerType = handlerType;
    Log.log('$handlerType initAudioSession start');
    WidgetsBinding.instance.addObserver(this);
    await _audioSessionUtil.initAudioSession(
      onDevicesChanged: onDevicesChanged,
      onDevices: onDevices,
      handlerType: handlerType
    );
    _hasInit = true;
    Log.log('$handlerType initAudioSession end');
  }

  Future<void> getAudioDevices() async{
    await _audioSessionUtil.getAudioDevices();
  }

  Future<List<BleDevice>> getA2dpConnectedDevices() async{
    return await _instance.getA2dpConnectedDevices();
  }

  Future<void> close() async{
    WidgetsBinding.instance.removeObserver(this);
    await _audioSessionUtil.close();
  }

  Duration _audioRouteCheckGap = const Duration(seconds: 3);
  void setAudioRouteCheckGap(Duration duration){
    _audioRouteCheckGap = duration;
    if(_audioRouteCheckTimer != null){
      startAudioRouteCheckTimer(); // restart timer
    }

  }

  Timer? _audioRouteCheckTimer;
  void startAudioRouteCheckTimer(){
    stopAudioRouteCheckTimer();
    _audioRouteCheckTimer = Timer.periodic(_audioRouteCheckGap, (_){
      Log.log('$handlerType active getAudioDevices');
      /// 主动拿当前耳机列表
      getAudioDevices();
    });
  }

  void stopAudioRouteCheckTimer(){
    if(_audioRouteCheckTimer != null){
      _audioRouteCheckTimer?.cancel();
      _audioRouteCheckTimer = null;
    }
  }

  /// 主要用于处理 IOS 不能实时响应那些，未在使用的耳机断连事件
  /// - 定时间隔时间检查下当前耳机列表（当在前台时）
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    Log.log('$handlerType AudioOutputDeviceNew $state hasInit $_hasInit');
    switch(state){
    /// the current state that user would like to know, they have to open
    /// the app first
      case AppLifecycleState.resumed:
      /// refresh state
        if(_hasInit){
          getAudioDevices();
          if(Platform.isIOS){
            /// 开始定时间隔时间检查下当前耳机列表
            startAudioRouteCheckTimer();
          }
        }
        break;
      default:
        if(_hasInit){
          if(Platform.isIOS){
            /// 关闭定时间隔时间检查下当前耳机列表
            stopAudioRouteCheckTimer();
          }
        }

        break;
    }
  }
}
